const { DataTypes, Model, Deferrable, TINYINT, INTEGER, Op } = require("sequelize");
const sequelize = require("../../sequelize");
/**
 * 商品分类模型
 */
class Category extends Model {
    /**
     * 异步子查父分类
     */
    async getParent() {
        //为0是没有父分类，返回自身的json格式
        if (this.category_id == 0) {
            return this.toJSON()
        }
        let parent = await Category.findOne({
            where: {
                id: this.category_id
            }
        })
        let json = this.toJSON()
        json["parent"] = await parent.getParent()
        return json
    }
    /**
     * 异步子查父分类
     * @param {*} id 
     */
    static async getParent(id) {
        let json = await Category.findOne({
            where: {
                id: id
            }
        })
        if (json == null) {
            return []
        }
        return json.getParent()
    }
    static async getCategoryAll() {
        let json = []
        await this.findAll({
            where: {
                category_id: 0
            }
        }).then(async row => {
            row.forEach(async (value) => {
                json.push(this.getChild(value.toJSON()));
            })
            json = await Promise.all(json)
        })
        return json
    }
    /**
     * 异步父查子
     * @param {} object 
     * @returns 
     */
    static async getChild(object) {
        if (!object.child) {
            object["child"] = []
        }
        let category = await Category.findAll({
            where: {
                "category_id": object.id
            }
        })
        if (category.length == 0) {
            delete object["child"]
            return object
        }
        for (let i = 0; i < category.length; i++) {
            let js = category[i].toJSON()
            js["child"] = []
            object["child"].push(Category.getChild(js))
        }
        object["child"] = await Promise.all(object["child"])
        return object
    }
    /**
     * 创建商品分类
     * @param {名称} name 
     * @param {是否启用} status 
     * @param {父分类id} category_id 
     * @param {排序权重} order 
     */
    static async addCategory(name, category_id,img) {
        return await this.create({
            name: name,
            status: 1,
            category_id: category_id,
            img:img,
            order: 50
        })
    }
    static async updateCategory(name, category_id, id) {
        return await this.update({
            name: name,
            category_id: category_id,
        }, {
            where: {
                id: id
            }
        })
    }
    static async updateStatus(id, status) {
        return await this.update({
            status: status
        }, {
            where: {
                id: id
            }
        })
    }
    //删除商品分类
    static async deleteCategory(id,deleteChild) {
        let js = (await this.findOne({
            where: {
                id: id
            }
        })).toJSON()
        if (js.category_id != 0) {
            Goods.resetCategoryId(id)
            return await this.destroy({
                where: {
                    id: id
                }
            })
        } else if(deleteChild) {
            //被删除的是父分类，跟随删除子分类
            return await this.deleteChild(id)
        }else{
            throw new Error("错误,被删除的是父分类且携带的参数不允许删除")
        }
    }
    /**
    * 异步父删子
    * @param {} object 
    * @returns 
    */
    static async deleteChild(childId) {
        let child = await Category.findAll({
            where: {
                "category_id": childId
            }
        })
        if (child.length == 0) {//没有子记录
            await Goods.resetCategoryId(childId)
            await Category.destroy({//删除
                where:{
                    id:childId
                }
            })
            return
        }
        for (let i = 0; i < child.length; i++) {
            await this.deleteChild(child[i].id)
        }
        await Goods.resetCategoryId(childId)
        await Category.destroy({//这里删除最外层的记录
            where:{
                id:childId
            }
        })
        return 
    }
};
Category.init({
    id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    name: {
        type: DataTypes.STRING
    },
    status: {
        type: TINYINT
    },
    category_id: {
        type: INTEGER
    },
    img:{
        type:DataTypes.TEXT
    },
    order: {
        type: INTEGER
    }
}, {
    sequelize,
    modelName: "Category",
    tableName: "category",
    createdAt:"create_time",
    updatedAt:"update_time"
})
module.exports = Category